package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net"
	"time"
)

const electrsURL = "192.168.0.233:52001"
var electrsPool = NewElectrsPool(electrsURL, 99) // 连接池大小最多为 99

type HeaderSubscription struct {
	ID     int          `json:"id"`
	Result HeaderResult `json:"result"`
}

type HeaderResult struct {
	Height int    `json:"height"`
	Hex    string `json:"hex"`
}

// This is an interface that sends requests to the Electrum Server through TCP
// func Electrsinterface(method string, params []interface{}) string {
// 	// Establish a TCP connection to the server
// 	conn, err := net.Dial("tcp", electrsURL)
// 	if err != nil {
// 		return ""
// 	}
// 	defer conn.Close()

// 	// 设置读/写超时时间，避免卡住
// 	conn.SetDeadline(time.Now().Add(60 * time.Second))

// 	data := map[string]interface{}{
// 		"method": method,
// 		"params": params,
// 		"id":     0,
// 	}

// 	payload, err := json.Marshal(data)
// 	if err != nil {
// 		return ""
// 	}
// 	// Send the request message to the server
// 	_, err = fmt.Fprintf(conn, "%s\n", payload)
// 	if err != nil {
// 		return ""
// 	}

// 	// Read the response message from the server
// 	responseBytes, err := bufio.NewReader(conn).ReadBytes('\n')
// 	if err != nil {
// 		return ""
// 	}
// 	return string(responseBytes)
// }
// func ElectrsBatchInterface(method string, paramsList [][]interface{}) []string {
// 	var responses []string

// 	for i, params := range paramsList {
// 		conn, err := net.Dial("tcp", electrsURL)
// 		if err != nil {
// 			fmt.Printf("Connection error for request %d: %v\n", i, err)
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 			continue
// 		}

// 		conn.SetDeadline(time.Now().Add(60 * time.Second)) // 设置超时
// 		defer conn.Close()

// 		requestData := map[string]interface{}{
// 			"method": method,
// 			"params": params,
// 			"id":     i,
// 		}

// 		requestBytes, err := json.Marshal(requestData)
// 		if err != nil {
// 			fmt.Printf("Marshal error for request %d: %v\n", i, err)
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 			continue
// 		}

// 		_, err = fmt.Fprintf(conn, "%s\n", requestBytes)
// 		if err != nil {
// 			fmt.Printf("Write error for request %d: %v\n", i, err)
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 			continue
// 		}

// 		respBytes, err := bufio.NewReader(conn).ReadBytes('\n')
// 		if err != nil {
// 			fmt.Printf("Read error for request %d: %v\n", i, err)
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 			continue
// 		}

// 		// 从JSON中提取result字段
// 		var parsed map[string]interface{}
// 		if err := json.Unmarshal(respBytes, &parsed); err != nil {
// 			fmt.Printf("Unmarshal error for response %d: %v\n", i, err)
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 			continue
// 		}

// 		if result, ok := parsed["result"]; ok {
// 			resultJSON, _ := json.Marshal(result)
// 			responses = append(responses, string(resultJSON))
// 		} else {
// 			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
// 		}
// 	}

// 	return responses
// }

//使用连接池 批量请求速度更快
func Electrsinterface(method string, params []interface{}) string {
	resp, err := electrsPool.Call(method, params)
	if err != nil {
		fmt.Println("Electrsinterface error:", err)
		return ""
	}
	return resp
}
func ElectrsBatchInterface(method string, paramsList [][]interface{}) []string {
	var responses []string

	// 假设 electrsPool 是已创建的连接池
	for i, params := range paramsList {
		conn, err := electrsPool.getConn() // 从连接池获取连接
		if err != nil {
			fmt.Printf("Connection error for request %d: %v\n", i, err)
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
			continue
		}

		conn.SetDeadline(time.Now().Add(60 * time.Second)) // 设置超时
		defer electrsPool.returnConn(conn) // 使用后归还连接池

		// 创建请求数据
		requestData := map[string]interface{}{
			"method": method,
			"params": params,
			"id":     i,
		}

		// 序列化请求数据
		requestBytes, err := json.Marshal(requestData)
		if err != nil {
			fmt.Printf("Marshal error for request %d: %v\n", i, err)
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
			continue
		}

		// 发送请求数据到连接
		_, err = fmt.Fprintf(conn, "%s\n", requestBytes)
		if err != nil {
			fmt.Printf("Write error for request %d: %v\n", i, err)
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
			continue
		}

		// 读取响应
		respBytes, err := bufio.NewReader(conn).ReadBytes('\n')
		if err != nil {
			fmt.Printf("Read error for request %d: %v\n", i, err)
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
			continue
		}

		// 从JSON中提取result字段
		var parsed map[string]interface{}
		if err := json.Unmarshal(respBytes, &parsed); err != nil {
			fmt.Printf("Unmarshal error for response %d: %v\n", i, err)
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
			continue
		}

		if result, ok := parsed["result"]; ok {
			resultJSON, _ := json.Marshal(result)
			responses = append(responses, string(resultJSON))
		} else {
			responses = append(responses, `{"confirmed":0,"unconfirmed":0}`)
		}
	}

	return responses
}

const maxBlocks = 1000

// This function subscribes to the BlockHeaders of the blockchain from Electrum
// Updates a Variable that is accessible in the blockheader endpoint to be returned
// This function should run on it's own thread in the background
func BlockWatcher(blocks *[]HeaderResult) {
	conn, err := net.Dial("tcp", electrsURL)
	if err != nil {
		//Error Out TODO
	}
	defer conn.Close()
	data := map[string]interface{}{
		"method": "blockchain.headers.subscribe",
		"params": []interface{}{},
		"id":     0,
	}
	payload, err := json.Marshal(data)
	if err != nil {
		//Error Handling TODO
	}
	// Send the request message to the server
	_, err = fmt.Fprintf(conn, "%s\n", payload)
	if err != nil {
		//Error Handling TODO
	}

	for {
		responseBytes, err := bufio.NewReader(conn).ReadBytes('\n')
		if err != nil {
			//Error Handling TODO
		}

		var response HeaderSubscription
		err = json.Unmarshal(responseBytes, &response)
		if err != nil {
			// Error Handling TODO
		}
		// 添加到 blocks，限制长度
		*blocks = append(*blocks, response.Result)
		if len(*blocks) > maxBlocks {
			// 丢弃最旧的一个
			*blocks = (*blocks)[1:]
		}
	}
}
